import re
from django import http
from django.conf import settings
from django.contrib.auth import login
from django.shortcuts import render, redirect
from QQLoginTool.QQtool import OAuthQQ
# Create your views here.
from django.urls import reverse
from django.views import View
from django_redis import get_redis_connection

from apps.carts.utils import merge_cart_cookie_to_redis
from apps.oauth.sinaweibopy3 import APIClient
from utils.secret import SecretOauth
from apps.ausers.models import User
from apps.oauth.models import OAuthQQUser, OAuthSinaUser
from meiduo_mall.settings.dev import logger
from utils.response_code import RETCODE

#1.获取qq的url
class QQAuthURLView(View):
    def get(self,request):
        next = request.GET.get('next')
        #实例化qq人认证
        oauth_qq = OAuthQQ(client_secret='418d84ebdc7241efb79536886ae95224',
                            client_id='101518219',
                            redirect_uri='http://www.meiduo.site:8000/oauth_callback',
                            state=next
                            )
        #获取登录网址
        login_url = oauth_qq.get_qq_url()
        #返回给前端
        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'login_url':login_url})


#判断是否绑定openid
def is_bind_openid(openid,request,next):

    try:
        oauth_user = OAuthQQUser.objects.get(openid=openid)
    # 2.未绑定 跳转到绑定页面
    except Exception as e:
        logger.error(e)
        data_dict = {'openid':openid}
        secret_openid = SecretOauth().dumps(data_dict)
        context = {'openid':secret_openid}
        return render(request,'oauth_callback.html', context)
    #1.绑定——>保持登录——>username 设置cookie——>跳转到首页
    user = oauth_user.user
    login(request,user)
    if next:
        response = redirect(next)
    else:
        response = redirect(reverse('contents:index'))
    response.set_cookie('username',user.username,max_age=3600*24*14)
    return response



#2. OAuth2.0认证获取openid
# http://www.meiduo.site:8000/oauth_callback?code=E4112FBF78FEAC257AB3D7C93D162E62&state=None
class QQAuthUserView(View):
    def get(self,request):
        next = request.GET.get('start')
        code = request.GET.get('code')

        if not code:
            return http.HttpResponseForbidden("缺少code")
        oauth_qq = OAuthQQ(client_secret='418d84ebdc7241efb79536886ae95224',
                           client_id='101518219',
                           redirect_uri='http://www.meiduo.site:8000/oauth_callback',
                           state=next
                           )

        try:
            #通过code获取token
            access_token = oauth_qq.get_access_token(code)
            #通过token获取openid
            openid = oauth_qq.get_open_id(access_token)
        except Exception as e:
            logger.error(e)
            return http.HttpResponseServerError("Oauth2.0认证失败")

        response = is_bind_openid(openid,request,next)

        return response


    def post(self,request):
        # 1.接受参数
        mobile = request.POST.get('mobile')
        pwd = request.POST.get('password')
        sms_code_client = request.POST.get('sms_code')
        openid = request.POST.get('openid')
        next = request.GET.get('state')
        # 2.解析参数
        #判空
        if not all([mobile, pwd, sms_code_client]):
            return http.HttpResponseForbidden('缺少必传参数')
        #正则
        # 判断手机号是否合法
        if not re.match(r'^1[3-9]\d{9}$', mobile):
            return http.HttpResponseForbidden('请输入正确的手机号码')
        # 判断密码是否合格
        if not re.match(r'^[0-9A-Za-z]{8,20}$', pwd):
            return http.HttpResponseForbidden('请输入8-20位的密码')
        # 3.校验短信
        # redis_conn = get_redis_connection('sms_code')
        # sms_redis_conn = redis_conn.get('sms_%s' % mobile)
        # if sms_redis_conn is None:
        #     return render(request, 'oauth_callback.html', {'sms_code_errmsg': '无效的短信验证码'})
        # if sms_code_client != sms_redis_conn.decode():
        #     return render(request, 'oauth_callback.html', {'sms_code_errmsg': '输入短信验证码有误'})
        openid = SecretOauth().loads(openid).get('openid', None)
        if not openid:
            return render(request, 'oauth_callback.html', {'openid_errmsg': '无效的openid'})
        # 4.判断用户  注册  存在登录
        try:
            user = User.objects.get(mobile = mobile)
        except Exception as e:
            logger.error(e)
            #不存在注册
            user = User.objects.create_user(username=mobile, password=pwd, mobile=mobile)
        else:
            if not user.check_password(pwd):
                return render(request, 'oauth_callback.html', {'account_errmsg': '用户名或密码错误'})
        # 5.user和openid
        try:
            OAuthQQUser.objects.create(openid=openid, user=user)
        except Exception as e:
            logger.error(e)
            return render(request, 'oauth_callback.html', {'qq_login_errmsg': 'QQ登录失败'})
        # 6.重定向到首页  保持登录 显示用户名
        login(request,user)
        if next:
            response = redirect(next)
        else:
            response = redirect(reverse('contents:index'))
        response.set_cookie('username',user.username,max_age=3600*24*14)
        merge_cart_cookie_to_redis(request, user, response)

        return response




class SinaLoginView(View):
    def get(self, request):
        from .sinaweibopy3 import APIClient
        oauth_sina = APIClient(
            app_key=settings.WEIBO_APP_ID,
            app_secret=settings.WEIBO_APP_KEY,
            redirect_uri=settings.WEIBO_REDIRECT_URI,
        )

        # 获取登录网址
        login_url = oauth_sina.get_authorize_url()

        return http.JsonResponse({'code': RETCODE.OK, 'errmsg': 'OK', 'login_url': login_url})

class SinaAuthUserView(View):
    def get(self, request):

        code = request.GET.get('code')

        oauth_sina = APIClient(
            app_key=settings.WEIBO_APP_ID,
            app_secret=settings.WEIBO_APP_KEY,
            redirect_uri=settings.WEIBO_REDIRECT_URI
        )
        try:
            # code > token
            # access_token = oauth_sina.request_access_token(code)['access_token']
            result = oauth_sina.request_access_token(code)
            # 通过ｃｏｄｅ获取ｕｉｄ和ｔｏｊｅｎ
            uid = result.uid
            access_token = result.access_token
            print(uid)

        except:
            return http.HttpResponseServerError('Oauth2.0认证失败！')
        try:
            user = OAuthSinaUser.objects.get(uid=uid)



        except:

            context = {'uid': uid}
            context = {'uid': SecretOauth().dumps(context)}


            return render(request, 'sina_callback.html', context)
        else:
            user = user.user
            login(request, user)
            response = redirect(reverse('contents:index'))
            response.set_cookie('username', user.username, max_age=3600 * 24 * 14)
            return response

    def post(self, request):
        # 接受参数
        mobile = request.POST.get('mobile')
        pwd = request.POST.get('password')
        sms_code = request.POST.get('sms_code')
        uid = request.POST.get('access_token')

        # 校验参数
        # 判断参数是否齐全
        if not all([mobile, pwd, sms_code, uid]):
            return http.HttpResponseForbidden("缺少必传参数")
        # 判断参数是否合法
        if not re.match(r"^1[3-9]\d{9}$", mobile):
            return http.HttpResponseForbidden('请输入正确手机号码')
        if not re.match(r'^[0-9A-Za-z]{8,20}$', pwd):
            return http.HttpResponseForbidden('请输入８－１６位的密码')
        sms_code_client = get_redis_connection('sms_code')
        sms_redis_code = sms_code_client.get("sms_%s" % mobile)
        # 判断验证码为空
        if sms_redis_code is None:
            return render(request, 'sina_callback.html', {'sms_code_errmsg': '无效的短信验证码'})
        # 判断验证码正确
        if sms_code != sms_redis_code.decode():
            return render(request, 'sina_callback.html', {'sms_code_errmsg': '输入短信验证码有误'})

        # 解密ｏｐｅｎｉｄ
        uid = SecretOauth().loads(uid).get('uid')
        if not uid:
            return render(request, 'sina_callback.html', {'uid_errmsg': '无效的uid'})

        # 保存注册数据
        try:
            user = User.objects.get(mobile=mobile)
        except Exception as e:
            logger.error(e)
            user = User.objects.create_user(username=mobile, password=pwd, mobile=mobile)
        else:
            # 判断密码是否正确
            if not user.check_password(pwd):
                return render(request, 'sina_callback.html', {'account_errmsg': '用户名或密码错误'})

        # 绑定用户ｏｐｅｎｉｄ
        try:
            OAuthSinaUser.objects.create(uid=uid, user=user)
        except Exception as e:
            logger.error(e)
            return render(request, 'sina_callback.html', {'sina_login_errmsg': 'QQ登录失败'})
        login(request, user)
        next = request.GET.get('state')
        response = redirect(redirect('contents:index'))
        merge_cart_cookie_to_redis(request=request, user=user, response=response)
        response.set_cookie('username', user.username, max_age=3600 * 24 * 15)

        return response


